package com.sjs.boot.dynamic.core.config.method.parameter;

import com.sjs.boot.dynamic.core.config.method.MethodConfig;
import com.sjs.boot.dynamic.core.run.MethodContext;
import com.sjs.boot.dynamic.util.ValParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author uto_dev_008
 * @desc
 * @since 2021/11/9 18:36
 * Copyright (c) 2021 南京友拓信息技术有限公司 All rights reserved
 */
public class CompoundParameterInfo extends ParameterInfo {
    private static final Logger LOG = LoggerFactory.getLogger(CompoundParameterInfo.class);
    private static final String CONFIG_SEGMENTS = "segments";
    private static final String CONFIG_NAME = "name";

    private String claim = "";

    private String name = "";
    private ParameterInfo[] segments = new ParameterInfo[0];

    public static final CompoundParameterInfo parse(String version, Map<String, Object> para, MethodConfig mc) {
        if (!para.containsKey(CONFIG_SEGMENTS) || !para.containsKey(CONFIG_NAME)) {
            LOG.error("No {} or {} in a typedefine", CONFIG_SEGMENTS, CONFIG_NAME);
            return null;
        }

        CompoundParameterInfo td = new CompoundParameterInfo();
        td.name = ValParser.getAsStr(para, CONFIG_NAME);
        ParameterInfo pi;
        int index = 1;
        List<Object> segs = ValParser.getAsList(para, CONFIG_SEGMENTS);
        List<ParameterInfo> segList = new ArrayList<ParameterInfo>();
        td.claim = "Compound parameter,segments[";

        for (Object o : segs) {
            if (!(o instanceof Map<?, ?>)) {
                LOG.error("Wrong segment definition of CompoundParameterInfo({})", td.name);
                return null;
            }

            if ((pi = ParameterInfo.parse(version, (Map<String, Object>) o, mc, index)) == null) {
                LOG.error("Wrong segment definition of CompoundParameterInfo({})", td.name);
                return null;
            }

            if (pi.getIndex() > 0) {
                index++;
            }

            segList.add(pi);
            td.claim += ',' + pi.getName();
        }

        if (segList.size() <= 0) {
            LOG.error("There are no segments in CompoundParameterInfo({})", td.name);
            return null;
        }
        td.segments = segList.toArray(new ParameterInfo[0]);
        td.claim += ']';

        return td;
    }

    @Override
    public boolean check(MethodContext context, Object para) {
        if (para instanceof Map<?, ?>) {
            Map<String, Object> o = (Map<String, Object>) para;

            for (ParameterInfo pi : segments) {
                if (!pi.check(context, o.get(pi.getName()))) {
//                    this.claim += "[parameter(" + pi.getName() + ")" + pi.getClaim() + "]";
                    return false;
                }
            }
            return true;
        }
        return segments[0].check(context, para); //简单类型，有且只有一个字段
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    protected boolean parseExt(String version, Map<String, Object> para, MethodConfig mc) {
        return true;
    }

    @Override
    protected boolean checkExt(MethodContext context, Object ele) {
        return true;
    }


    @Override
    public Object getValue(MethodContext context) {
        return null;
    }

    @Override
    public String getClaim() {
        return claim;
    }

    @Override
    public boolean isPrimitive() {
        return false;
    }

    public ParameterInfo[] getSegments() {
        return segments;
    }
}
